package com.yuanian.timingwheel.model.task.base;

import com.yuanian.timingwheel.context.ExecutionContext;
import com.yuanian.timingwheel.respository.po.TaskEntity;
import java.util.Date;

/**
 * 任务的信息，所有的任务归根结底都是在执行时间去执行，执行多少次，间隔多长时间
 */
public class TaskExecutionInfo {

    //间隔秒数
    protected long executionInterval;
    //执行次数
    protected long executionRounds;
    //下次执行时间
    protected Date executionTime;
    //已经执行次数
    protected long executedRounds;

    public TaskExecutionInfo(long executionInterval, long executionRounds, Date executionTime) {
        this(executionInterval, executionRounds, 0, executionTime);
    }

    public TaskExecutionInfo(long executionInterval, long executionRounds, long executedRounds, Date executionTime) {
        this.executionInterval = executionInterval;
        this.executionRounds = executionRounds;
        this.executionTime = executionTime;
        this.executedRounds = executedRounds;
    }

    /**
     * 是否还可以运行
     * @return
     */
    private boolean canExecute() {
        return this.executionInterval > 0 && this.executionRounds > 0 && this.executionRounds > this.executedRounds;
    }

    /**
     * 任务执行后置操作
     */
    public void postExecute(BaseTask task) {
        ExecutionContext.getInstance().addExecutedTaskCnt();
        executedRounds++;
        System.out.println("任务结束执行，当前执行次数为：" + executedRounds + ",日级时间轮已经执行的任务数量：" + ExecutionContext.getInstance().getExecutedTaskCnt());
        if (canExecute()) {
            //从当前时间算，而不是从执行时间算
            executionTime.setTime(new Date().getTime() + executionInterval * 1000);
            TaskEntity.update(task);
            //重新加入任务
            ExecutionContext.getInstance().getDayTimingWheel().loadTask(task);
        } else {
            TaskEntity.update(task);
        }
    }

    public long getExecutionInterval() {
        return executionInterval;
    }

    public void setExecutionInterval(long executionInterval) {
        this.executionInterval = executionInterval;
    }

    public long getExecutionRounds() {
        return executionRounds;
    }

    public void setExecutionRounds(long executionRounds) {
        this.executionRounds = executionRounds;
    }

    public Date getExecutionTime() {
        return executionTime;
    }

    public void setExecutionTime(Date executionTime) {
        this.executionTime = executionTime;
    }

    public long getExecutedRounds() {
        return executedRounds;
    }

    public void setExecutedRounds(long executedRounds) {
        this.executedRounds = executedRounds;
    }
}
